#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   App_SecurityAccess_0x27_test.py
@Time    :   2024/09/14 13:31:28
@Author  :   yangliang    
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from pytest_assume.plugin import assume

import pytest
import logging
import time
import requests
from sympy import I
# from sympy import assuming
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable

from sqlalchemy import false
sys.dont_write_bytecode = True

SecurityAccess_Seed_NRC = [([0x27], [0x7F, 0x27, 0x13]),
                           ([0x27, 0x01, 0x15], [0x7F, 0x27, 0x13]),
                           ([0x27, 0x01, 0xFF], [0x7F, 0x27, 0x13]),
                           ([0x27, 0x11, 0xFF], [0x7F, 0x27, 0x7E]),
                           ([0x27, 0x12, 0xFF], [0x7F, 0x27, 0x7E]),
                           ([0x27, 0x05, 0x11], [0x7F, 0x27, 0x12]),
                           ([0x27, 0x11], [0x7F, 0x27, 0x7E]),
                           ([0x27, 0x05], [0x7F, 0x27, 0x12]),
                           ([0x27, 0x07], [0x7F, 0x27, 0x12])]

SecurityAccess_Key_NRC = [([0x27], [0x7F, 0x27, 0x13]),
                          ([0x27, 0x02], [0x7F, 0x27, 0x13]),
                          ([0x27, 0x02, 0xFF], [0x7F, 0x27, 0x13]),
                          ([0x27, 0x02, 0x11, 0x33, 0x22], [0x7F, 0x27, 0x13]),
                          ([0x27, 0x12, 0x11, 0x33, 0x22], [0x7F, 0x27, 0x7E]),
                          ([0x27, 0x12], [0x7F, 0x27, 0x7E]),
                          ([0x27, 0x06], [0x7F, 0x27, 0x12]),
                          ([0x27, 0x08], [0x7F, 0x27, 0x12])]


class Test_SecurityAccess_Phy(object):

    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    # BAIC_B41V-1045:某安全等级处于Locked状态，如果tester发送“request seed”，ECU不应该发送值为0的种子。
    # 如果tester连续发送“request seed”，ECU应该返回相同的seed，但FAC应该加1，如果由于连续发送“request seed”导致FAC等于3（即第四次连续请求种子），ECU回复NRC 0x37的否定响应之后再执行10s延时
    def test_SecurityAccess_Seed_Phy(self, action, Driver, unlock_App):
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        with assume:
            assert (uds_resp[0:2] == [0x67, 0x01] and size == 18)

        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        with assume:
            assert (uds_resp[0:2] == [0x67, 0x01] and size == 18)

        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        with assume:
            assert (uds_resp[0:2] == [0x67, 0x01] and size == 18)

        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)

        for i in range(4):
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            time.sleep(3)
            logging.info('wait 3s')
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, True)

    @allure.severity('minor')
    @allure.description('Test NRC of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_Seed_NRC_Phy(self, action, Driver, unlock_App):
        iStep = 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 7F', 1, iStep, False)
        seed = []
        iStep, uds_rep_seed, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
        for i in range(5):
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            logging.info('wait 3 seconds')
            time.sleep(3)

        logging.info('wait 15 seconds for FAC timeout')
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)

        for i in range(4):
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)
            time.sleep(2)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)

        time.sleep(2)
        # 安全访问延时溢出后FAC减1，即允许一次安全访问。
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        with assume:
            assert (uds_rep[0:2] == [0x67, 0x01] and size == 18)
        for i in range(16):
            seed.append(uds_rep[2+i])
        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)



    ids = ['Request {0}'.format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in SecurityAccess_Seed_NRC]
    @allure.severity('minor')
    @allure.description('Test NRC of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', SecurityAccess_Seed_NRC, ids=ids)
    def test_SecurityAccess_Seed_NRC12_13_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)
        time.sleep(1)
        seed = []
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        with assume:
            assert (uds_rep[0:2] == [0x67, 0x01] and size == 18)

        for i in range(16):
            seed.append(uds_rep[2+i])
        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)
        # 会话跳转
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep, False)

    @pytest.mark.smoke
    @allure.severity('normal')
    @allure.description('Test positive response of 0x27 key in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_Key_Phy(self, action, Driver, unlock_App):
        seed = []
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        seed = uds_rep[2:]
        logging.info(f'seed:{seed}')
        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)
        time.sleep(12)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        seed = uds_rep[2:]
        logging.info(f'seed:{seed}')
        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)

    @allure.severity('minor')
    @allure.description('Test NRC of 0x27 key in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_Key_NRC_Phy(self, action, Driver, unlock_App):
        seed = []
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 11 11', '7F 27 13', 3, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        seed = uds_rep[2:]
        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 12 ' + ' '.join(['22' * 32]), '7F 27 7E', 0, iStep, False)
        
        Driver['power'].set_vltage(0)
        time.sleep(5)
        Driver['power'].set_vltage(12)
        time.sleep(5)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)
        # Test NRC36 of key of 0x27
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)
        

        # Test NRC37 of key of 0x27
        #8s内Request:0x27,0x01, # Response:0x7F,0x27,0x37, Request:0x27,0x02,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, # Response:0x7F,0x27,0x24"):
        for i in range(4):
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)
            time.sleep(2)

        time.sleep(1)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)

        time.sleep(2)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)

        # 安全访问延时溢出后FAC减1，FAC=2，后再Request:invalid key，FAC=3，响应NRC36
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)
        time.sleep(11)

    ids = ['Request {0}'.format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in SecurityAccess_Key_NRC]
    @allure.severity('minor')
    @allure.description('Test NRC of 0x27 key in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', SecurityAccess_Key_NRC, ids=ids)
    def test_SecurityAccess_Key_NRC12_13_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)    

    @allure.severity('minor')
    @allure.description('Test FAC will not be lost after ECU is restarted (reset)  in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_FAC_Continue_Accumulation_After_Reset_Phy(self, action, Driver, extend_unlock, unlock_App):
        # test ECU重启（复位）后不会丢失FAC
        # 上电、复位后，ECU首先检查各个安全等级的FAC，如果FAC小于3，ECU无需执行安全访问延时
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False)  
    
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '11 01', '51 01', 0, iStep, False) 
        time.sleep(3)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False) 
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False) 
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False) 
        time.sleep(11)

    @allure.severity('minor')
    @allure.description('Test FAC will not be lost after ECU is restarted (powered down)  in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_FAC_Continue_Accumulation_After_Powerdown_Phy(self, action, Driver, extend_unlock, unlock_App):
        # test ECU重启（下上电）后不会丢失FAC
        # 上电、复位后，ECU首先检查各个安全等级的FAC，如果FAC小于3，ECU无需执行安全访问延时
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False) 
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False) 
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)
        time.sleep(1)
        with allure.step(f"Step{iStep}:Power off then power on"):
            Driver['power'].set_vltage(0)
            time.sleep(3)
            Driver['power'].set_vltage(12)
            time.sleep(3)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 3, iStep, False) 
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 3, iStep, False) 
        time.sleep(13)

    @allure.severity('minor')
    @allure.description('Test ECU will be executed session jump, and "seed key" sequence will be reset in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_sequence_after_session_jump_Phy(self, action, Driver, extend_unlock, unlock_App):
        # Test ECU执行会话跳转，“Seed—Key” 序列将被重置
        seed = []
        with allure.step("Step1:Request:0x27,0x01, # Response:0x67,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x27, 0x01], 2)
            if uds_rep[0:2] != [0x67, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x67,0x01], actual response:[{actuRespStr}]')
            with assume:
                assert (uds_rep[0:2] == [0x67, 0x01] and size == 18)

            seed = uds_rep[2:]
            key = Driver['CAN'].calcKey(seed)
            send_key = [0x27, 0x02] + key
        with allure.step("Step4:Request:{0}, # Response:0x67,0x02".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:2] != [0x67, 0x02]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                correct_send_key = binascii.b2a_hex(bytearray(send_key), ' ')
                logging.error(
                    f'correct response:[{correct_send_key}], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x67, 0x02]
        # 会话跳转
        with allure.step("Step2:Request:0x10 0x01, # Response:0x50,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x10, 0x01], 2)
            if uds_rep[0:2] != [0x50, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x50,0x01,0x00,0x32,0x00,0xC8], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x50, 0x01]
        with allure.step("Step3:Request:0x10 0x03, # Response:0x50,0x03"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x10, 0x03], 2)
            if uds_rep[0:2] != [0x50, 0x03]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x50,0x03,0x00,0x32,0x00,0xC8], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x50, 0x03]
        with allure.step("Step4:Request:{0}, # Response:0x7F,0x27,0x24".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:3] != [0x7F, 0x27, 0x24]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x7F,0x27,0x24], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:3] == [0x7F, 0x27, 0x24]

    @allure.severity('minor')
    @allure.description('Test ECU will be powered on again,"seed key" sequence will be reset in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_sequence_after_poweron_again_Phy(self, action, Driver, extend_unlock, unlock_App):
        # Test ECU被重新上电，“Seed—Key” 序列将被重置
        seed = []
        with allure.step("Step1:Request:0x27,0x01, # Response:0x67,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x27, 0x01], 2)
            if uds_rep[0:2] != [0x67, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x67,0x01], actual response:[{actuRespStr}]')
            with assume:
                assert (uds_rep[0:2] == [0x67, 0x01] and size == 18)

            seed = uds_rep[2:]

            key = Driver['CAN'].calcKey(seed)
            send_key = [0x27, 0x02] + key
        with allure.step("Step4:Request:{0}, # Response:0x67,0x02".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:2] != [0x67, 0x02]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                correct_send_key = binascii.b2a_hex(bytearray(send_key), ' ')
                logging.error(
                    f'correct response:[{correct_send_key}], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x67, 0x02]
        # ECU被重新上电
        with allure.step("Step2:Power off then power on"):
            Driver['power'].set_vltage(0)
            time.sleep(3)
            Driver['power'].set_vltage(12)
            time.sleep(3)

        with allure.step("Step3:Request:0x10 0x01, # Response:0x50,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x10, 0x01], 2)
            if uds_rep[0:2] != [0x50, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(f'correct response:[0x50,0x01,0x00,0x32,0x00,0xC8], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x50, 0x01]
        with allure.step("Step4:Request:0x10 0x03, # Response:0x50,0x03"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x10, 0x03], 2)
            if uds_rep[0:2] != [0x50, 0x03]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x50,0x03,0x00,0x32,0x00,0xC8], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x50, 0x03]
        with allure.step("Step5:Request:{0}, # Response:0x7F,0x27,0x24".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:3] != [0x7F, 0x27, 0x24]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x7F,0x27,0x24], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:3] == [0x7F, 0x27, 0x24]

    @allure.severity('minor')
    @allure.description('Test ECU will be reset, "seed key" sequence will be reset in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_sequence_after_reset_Phy(self, action, Driver, extend_unlock, unlock_App):
        # Test ECU被复位，“Seed—Key” 序列将被重置
        seed = []

        with allure.step("Step2:Request:0x27,0x01, # Response:0x67,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x27, 0x01], 2)
            if uds_rep[0:2] != [0x67, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x67,0x01], actual response:[{actuRespStr}]')
            with assume:
                assert (uds_rep[0:2] == [0x67, 0x01] and size == 18)

            seed = uds_rep[2:]

            key = Driver['CAN'].calcKey(seed)
            send_key = [0x27, 0x02] + key
        with allure.step("Step4:Request:{0}, # Response:0x67,0x02".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:2] != [0x67, 0x02]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                correct_send_key = binascii.b2a_hex(bytearray(send_key), ' ')
                logging.error(
                    f'correct response:[{correct_send_key}], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x67, 0x02]
        # 复位
        with allure.step("Step3:Request:0x11 0x01, # Response:0x51,0x01"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x11, 0x01], 2)
            if uds_rep[0:2] != [0x51, 0x01]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x51,0x01], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x51, 0x01]
            time.sleep(2)
        with allure.step("Step4:Request:0x10 0x03, # Response:0x50,0x03"):
            uds_rep, size = Driver['UDS'].req_and_res_can([0x10, 0x03], 2)
            if uds_rep[0:2] != [0x50, 0x03]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x50,0x03,0x00,0x32,0x00,0xC8], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:2] == [0x50, 0x03]
        with allure.step("Step5:Request:{0}, # Response:0x7F,0x27,0x24".format(send_key)):
            uds_rep, size = Driver['UDS'].req_and_res_can(
                send_key, len(send_key))
            if uds_rep[0:3] != [0x7F, 0x27, 0x24]:
                actuRespStr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                logging.error(
                    f'correct response:[0x7F,0x27,0x24], actual response:[{actuRespStr}]')
            with assume:
                assert uds_rep[0:3] == [0x7F, 0x27, 0x24]

    @allure.severity('minor')
    @allure.description('Test under delay response of 0x27 key then reset ECU in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_under_delay_then_reset_Phy(self, action, Driver, extend_unlock, unlock_App):
        seed = []
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        # Test NRC36 of key of 0x27
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)
        
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
        time.sleep(0.3)
        logging.info('wait 300ms')
        # 复位
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '11 01', '51 01', 0, iStep, False)
        time.sleep(1)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False)
        for i in range(4):
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)
            time.sleep(2.5)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        seed = uds_rep[2:]

        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)
 

    @allure.severity('minor')
    @allure.description('Test under delay response of 0x27 key then powerreset ECU in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    def test_SecurityAccess_under_delay_then_powerreset_Phy(self, action, Driver, extend_unlock, unlock_App):
        # Test ECU 在delay过程中 重新上电, 安全访问请求,收到负响应，有访问延时（重新计时10s---9月9号邮件回复）
        # 上电、复位后，ECU首先检查各个安全等级的FAC，如果FAC大于3，应该执行安全访问延时（延时时间为10s），并将FAC赋值为3
        seed = []
        iStep = 1
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 35', 0, iStep, False)

        # Test NRC36 of key of 0x27
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 36', 0, iStep, False)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
        time.sleep(2)

        # ECU被重新上电
        with allure.step(f"Step{iStep}:Power off then power on"):
            Driver['power'].set_vltage(0)
            time.sleep(1)
            Driver['power'].set_vltage(12)
            time.sleep(3)
            iStep += 1

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '10 03', '50 03', 0, iStep, False)
        # Test NRC37 of key of 0x27
        for i in range(4):
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '7F 27 37', 0, iStep, False)
            iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 02 ' + ' '.join(['22' * 32]), '7F 27 24', 0, iStep, False)
            time.sleep(2)

        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, '27 01', '67 01', 0, iStep, False)
        seed = uds_rep[2:]

        key = Driver['CAN'].calcKey(seed)
        send_key = [0x27, 0x02] + key
        iStep, uds_rep, size = Driver['CAN'].checkReqResp(Driver, send_key, '67 02', 0, iStep, False)

    
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_Three_Seed_Extended_Phy(self,action,Driver, unlock_App):
        iStep = 1
        time.sleep(5)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 3, iStep, False)
        seed1 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.8)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 0, iStep, False)
        seed2 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.8)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 0, iStep, False)
        seed3 = uds_resp[2:]
        with assume: assert size == 18

        same1_2 = np.array_equal(seed1, seed2)
        same1_3 = np.array_equal(seed1, seed3)
        same2_3 = np.array_equal(seed2, seed3)

        with assume: assert same1_2 == True and same1_3 == True and same2_3 == True

    
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in programming session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_Three_Seed_Programming_Phy(self,action,Driver, unlock_App):
        iStep = 1
        time.sleep(0.1)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x11], [0x67,0x11], 2, iStep, False)
        seed1 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.2)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x11], [0x67,0x11], 0, iStep, False)
        seed2 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.2)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x11], [0x67,0x11], 0, iStep, False)
        seed3 = uds_resp[2:]
        with assume: assert size == 18

        same1_2 = np.array_equal(seed1, seed2)
        same1_3 = np.array_equal(seed1, seed3)
        same2_3 = np.array_equal(seed2, seed3)

        with assume: assert same1_2 == True and same1_3 == True and same2_3 == True

     
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_Three_Seed_NRC37_Phy(self,action,Driver, unlock_App):
        iStep = 1
        time.sleep(0.1)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 3, iStep, False)
        seed1 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.2)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 0, iStep, False)
        seed2 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.2)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 0, iStep, False)
        seed3 = uds_resp[2:]
        with assume: assert size == 18
        time.sleep(0.2)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x7F,0x27,0x37], 0, iStep, False)
        key = Driver['CAN'].calcKey(seed2)
        send_key = [0x27,0x02] + key
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, send_key, [0x7F,0x27,0x37], 0, iStep, False)

     
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_changeSession_Phy(self,action,Driver, unlock_App):
        iStep = 1
        time.sleep(0.1)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 3, iStep, True)
        time.sleep(0.1)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x10,0x03], [0x50,0x03], 0, iStep, False)
        time.sleep(0.1)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 0, iStep, False)
        seed = uds_resp[2:]
        with assume: assert size == 18
        with assume: assert seed != [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]

     
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in extended session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_Seed_kpi_Extended_Phy(self,action,Driver, unlock_App):
        iStep = 1
        seed = []
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 3, iStep, False)
        for i in range(200):
            time.sleep(0.1)
            iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x01], [0x67,0x01], 3, iStep, False)
            seedTemp = uds_resp[2:]
            if seedTemp not in seed:
                seed.append(seedTemp)
            if i % 5 == 0 and i % 10 != 0:
                iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
                iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 0, iStep, False)

            if i % 10 == 0:
                iStep = Driver['CAN'].restartMRR_11(Driver,iStep)
                iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 0, iStep, False)

            if i % 50 == 0:
                logging.info(f'{i + 1}次不重复的种子数是：[{len(seed)}]个')


        logging.info(f'{i + 1}次不重复的种子数是：[{len(seed)}]个')

        with assume: assert len(seed)/(i+1) > 0.95

    
    @allure.severity('normal')
    @allure.story('Tester Security Access')
    @allure.description('Test positive response of 0x27 seed in programming session with physical addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
    def test_SecurityAccess_Seed_kpi_Programming_Phy(self,action,Driver):
        iStep = 1
        seed = []
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 2, iStep, False)
        for i in range(200):
            time.sleep(0.1)
            iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x27,0x11], [0x67,0x11], 2, iStep, False)
            seedTemp = uds_resp[2:]
            if seedTemp not in seed:
                seed.append(seedTemp)
            if i % 5 == 0 and i % 10 != 0:
                iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
                iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 0, iStep, False)

            if i % 10 == 0:
                iStep = Driver['CAN'].restartMRR_11(Driver,iStep)
                iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], 0, iStep, False)

            if i % 50 == 0:
                logging.info(f'{i + 1}次不重复的种子数是：[{len(seed)}]个')


        logging.info(f'{i + 1}次不重复的种子数是：[{len(seed)}]个')

        with assume: assert len(seed)/(i+1) > 0.95
